<?php

declare(strict_types=1);

namespace App\Model;
use App\Model\PayOrder;
use App\Model\UserProfile;

use Hyperf\DbConnection\Db;
use Hyperf\DbConnection\Model\Model;

/**
 *  金币日志记录
 */
class CoinLog extends Model
{
    protected $table = 'coin_log';

    //充值
    const TYPE_RECHARGE = 1;
    //消费
    const TYPE_CONSUME = 2;
    //收入
    const TYPE_INCOME = 3;

    //来源-个人中心充值
    const FROM_RECHARGE = 1;
    //来源-新手福利
    const FROM_NEW = 2;
    //来源-语音电话消费
    const FROM_VOICECALL_OUT = 3;
    //来源-语音电话收入
    const FROM_VOICECALL_IN = 4;
    //提现
    const FROM_WITHDRAW = 6;
    //来源-首充赠送
    const FROM_FIRST_RECHARGE = 7;
    //来源-充值特惠赠送
    const FROM_RECHARGE_SEND = 8;
    //提现
    const FROM_WITHDRAW_BACK = 9;
    //每日任务奖励
    const FROM_DAILY_TASK = 10;
    //收到礼物
    const FROM_GET_GIFT = 11;
    //送出礼物
    const FROM_SEND_GIFT = 12;
    //收到系统礼物
    const FROM_GET_SYSGIFT = 13;
    //来源-视频通话消费
    const FROM_VIDEOCALL_OUT = 14;
    //来源-视频通话收入
    const FROM_VIDEOCALL_IN = 15;
    //天天免费福利
    const FROM_DAILY_FREE = 16;
    //语音随心聊支出
    const FROM_QUICK_VOICE_OUT = 17;
    //语音随心聊收入
    const FROM_QUICK_VOICE_IN = 18;
    //视频随心聊支出
    const FROM_QUICK_VIDEO_OUT = 19;
    //视频随心聊收入
    const FROM_QUICK_VIDEO_IN = 20;
    //来源-邀请奖励（通话收入）
    const FROM_INVITE_INCOME_CALL = 5;
    //来源-邀请奖励（礼物收入）
    const FROM_INVITE_INCOME_GIFT = 21;
    //来源-邀请奖励（充值）
    const FROM_INVITE_RECHARGE = 22;
    //来源-邀请奖励（私信收入）
    const FROM_INVITE_PRIVATE_MSG = 23;
    //来源-私信消费
    const FROM_SEND_PRIVATE_MSG_OUT = 24;
    //来源-私信收入
    const FROM_SEND_PRIVATE_MSG_IN = 25;
    //天天福利-充值奖励
    const FROM_DAILY_FREE_RECHARGE = 26;
    //资料完善
    const FROM_PROFILE_FIX = 27;
    //查看微信支出
    const FROM_CHECK_WECHAT_OUT = 28;
    //查看微信收入
    const FROM_CHECK_WECHAT_IN = 29;
    //查看微信退回
    const FROM_CHECK_WECHAT_BACK = 30;
    //许愿活动支出
    const FROM_ACT_MAKE_WISH = 31;
    //许愿树活动-金币中奖收入
    const FROM_ACT_MAKE_WISH_COIN_IN = 32;
    //签到收入
    const FROM_SIGNIN = 33;
    //今日缘分-打招呼
    const FROM_SEND_GREET_MSG_OUT = 34;
    //今日缘分-打招呼
    const FROM_SEND_GREET_MSG_IN = 35;
    //新人专享私信收入
    const FROM_NEW_FREE_MSG_IN = 36;
    //新人指南任务
    const FROM_NEW_GUIDE_TASK = 37;
    //邀约视频
    const FROM_INVITE_VIDEO = 38;
    //女生注册推送礼物
    const FROM_FEMALE_PUSH_GIFT = 39;
    //系统扣币
    const FROM_SYS_COST = 100;
    //系统补币
    const FROM_SYS_GAIN = 101;
    //来源-视频通话收入
    const FROM_DISCOUNT_VIDEO_CALL_IN = 102;
    //来源-视频通话支出
    const FROM_DISCOUNT_VIDEO_CALL_OUT = 103;

    //来源描述
    const FROM_DETAIL = [
        self::FROM_RECHARGE => '充值',
        self::FROM_NEW => '语聊 (新手福利)',
        self::FROM_VOICECALL_OUT => '语音通话支出',
        self::FROM_VOICECALL_IN => '语音通话收入',
        self::FROM_WITHDRAW => '申请提现',
        self::FROM_FIRST_RECHARGE => '首充赠送',
        self::FROM_RECHARGE_SEND => '充值赠送',
        self::FROM_WITHDRAW_BACK => '退回金币 (提现审核不通过)',
        self::FROM_SYS_COST => '系统扣币',
        self::FROM_SYS_GAIN => '系统补币',
        self::FROM_DAILY_TASK => '每日任务奖励',
        self::FROM_GET_GIFT => '收到礼物',
        self::FROM_SEND_GIFT => '送出礼物',
        self::FROM_GET_SYSGIFT => '收到打招呼礼物',
        self::FROM_VIDEOCALL_OUT => '视频通话支出',
        self::FROM_VIDEOCALL_IN => '视频通话收入',
        self::FROM_DAILY_FREE => '天天福利通话',
        self::FROM_QUICK_VOICE_OUT => '语音随心聊支出',
        self::FROM_QUICK_VOICE_IN => '语音随心聊收入',
        self::FROM_QUICK_VIDEO_OUT => '视频随心聊支出',
        self::FROM_QUICK_VIDEO_IN => '视频随心聊收入',
        self::FROM_INVITE_INCOME_CALL => '（通话收入）',
        self::FROM_INVITE_INCOME_GIFT => '（礼物收入）',
        self::FROM_INVITE_RECHARGE => '（充值）',
        self::FROM_INVITE_PRIVATE_MSG => '（私信收入）',
        self::FROM_SEND_PRIVATE_MSG_OUT => '赠送消息',
        self::FROM_SEND_PRIVATE_MSG_IN => '私信收入',
        self::FROM_DAILY_FREE_RECHARGE => '速配通话的充值返利',
        self::FROM_PROFILE_FIX => '资料完善奖励',
        self::FROM_CHECK_WECHAT_OUT => '查看微信支出',
        self::FROM_CHECK_WECHAT_IN => '查看微信收入',
        self::FROM_CHECK_WECHAT_BACK => '查看微信退回',
        self::FROM_ACT_MAKE_WISH => '许愿活动支出',
        self::FROM_ACT_MAKE_WISH_COIN_IN => '许愿活动金币礼物',
        self::FROM_SIGNIN => '签到奖励',
        self::FROM_SEND_GREET_MSG_OUT => '打招呼消息支出',
        self::FROM_SEND_GREET_MSG_IN => '打招呼消息收入',
        self::FROM_NEW_FREE_MSG_IN => '新人专享私信收入',
        self::FROM_NEW_GUIDE_TASK => '新人指南任务奖励',
        self::FROM_INVITE_VIDEO => '视频约会',
        self::FROM_FEMALE_PUSH_GIFT => '收到新人礼物',
        self::FROM_DISCOUNT_VIDEO_CALL_IN => '特惠视频收入',
        self::FROM_DISCOUNT_VIDEO_CALL_OUT => '特惠视频支出',
    ];

    const VOICE_CALL_INCOME = [self::FROM_VOICECALL_IN, self::FROM_QUICK_VOICE_IN, self::FROM_DAILY_FREE];
    const VIDEO_CALL_INCOME = [self::FROM_VIDEOCALL_IN, self::FROM_QUICK_VIDEO_IN, self::FROM_DAILY_FREE, self::FROM_DISCOUNT_VIDEO_CALL_IN, self::FROM_INVITE_VIDEO];

    const FREE_INCOME = [
        self::FROM_QUICK_VIDEO_IN,
        self::FROM_NEW_FREE_MSG_IN,
        self::FROM_INVITE_PRIVATE_MSG,
        self::FROM_INVITE_RECHARGE,
        self::FROM_INVITE_INCOME_GIFT,
        self::FROM_INVITE_INCOME_CALL,
        self::FROM_QUICK_VIDEO_IN,
        self::FROM_DAILY_FREE,
    ];

    /**
     * 获取收支明细记录
     */
    static function getDetailList($userId = 0, $page = 0, $pageNum = 20)
    {
        $where = [
            ['user_id', $userId],
            ['flag', 1],
            ['coin', '>', 0]
        ];
        $start = ($page - 1) * $pageNum;
        return self::where($where)->orderBy('id', 'desc')->offset($start)->limit($pageNum)->get()->toArray();
    }
    /**
     * 构造列表元素
     */
    static function buildItem($item, $callsInfo = [])
    {
        $mark = $item['log_type'] == self::TYPE_CONSUME ? '-' : '+';
        $title = self::FROM_DETAIL[$item['from']] ?? '未知';
        //天天福利区分视频-语音
        if ($callsInfo && $item['from'] == self::FROM_DAILY_FREE) {
            $title .= isset($callsInfo[$item['order_id']]) && $callsInfo[$item['order_id']] == VoiceCall::CALL_TYPE ? '（语音）' : '（视频）';
	}

	$inviteInfo = '';
        if (in_array($item['from'],array(5,21,22,23))) {
	    $userWhere = [
                ['user_id', '=', $item['op_user_id']]
            ];
            $userProfileInfo = UserProfile::where($userWhere)->first();
            $inviteInfo = '(ID:'. $userProfileInfo->user_profile_id .')';
        }

        return [
            'title' => $title . $inviteInfo,
            'log_time' => (string)$item['created_at'],
            'coin' => "{$mark}{$item['coin']}",
            'total_remain' => $item['remain_income_coin'] + $item['remain_recharge_coin'],
    	];
    }

    /**
     * 添加充值记录
     */
    static function addReCharge(
        $userId = 0,
        $coin = 0,
        $orderId = '',
        $remainCoin = [],
        $from = self::FROM_RECHARGE
    ) {
        $model = new self();
        $model->user_id = $userId;
        $model->coin = $coin;
        $model->order_id = $orderId;
        $model->remain_recharge_coin = $remainCoin['recharge_coin'] ?? 0;
        $model->remain_income_coin = $remainCoin['income_coin'] ?? 0;
        $model->log_type = self::TYPE_RECHARGE;
        $model->from = $from;
        return $model->saveOrFail() ? 1 : 0;
    }

    /**
     * 添加消费记录
     */
    static function addConsume(
        $userId = 0,
        $coin = 0,
        $from = self::FROM_VOICECALL_OUT,
        $remainCoin = [],
        $orderId = '',
        $opUserId = 0
    ) {
        $model = new self();
        $model->user_id = $userId;
        $model->coin = $coin;
        $model->remain_recharge_coin = $remainCoin['recharge_coin'] ?? 0;
        $model->remain_income_coin = $remainCoin['income_coin'] ?? 0;
        $model->from = $from;
        $model->log_type = self::TYPE_CONSUME;
        $model->order_id = $orderId;
        $model->op_user_id = $opUserId;
        return $model->saveOrFail() ? 1 : 0;
    }

    /**
     * 添加收入记录
     */
    static function addIncome(
        $userId = 0,
        $coin = 0,
        $from = self::FROM_VOICECALL_IN,
        $remainCoin = [],
        $orderId = '',
        $opUserId = 0
    ) {
        $model = new self();
        $model->user_id = $userId;
        $model->coin = $coin;
        $model->from = $from;
        $model->remain_recharge_coin = $remainCoin['recharge_coin'] ?? 0;
        $model->remain_income_coin = $remainCoin['income_coin'] ?? 0;
        $model->log_type = self::TYPE_INCOME;
        $model->order_id = $orderId;
        $model->op_user_id = $opUserId;
        return $model->saveOrFail() ? 1 : 0;
    }

    /**
     * 额外记录
     */
    static function addExtraIncome(
        $userId = 0,
        $coin = 0,
        $from = self::FROM_VOICECALL_IN,
        $remainCoin = [],
        $orderId = '',
        $opUserId = 0
    ) {
        $model = new self();
        $model->user_id = $userId;
        $model->coin = $coin;
        $model->from = $from;
        $model->remain_recharge_coin = $remainCoin['recharge_coin'] ?? 0;
        $model->remain_income_coin = $remainCoin['income_coin'] ?? 0;
        $model->log_type = self::TYPE_INCOME;
        $model->order_id = $orderId;
        $model->op_user_id = $opUserId;
        $model->flag = 3;
        return $model->saveOrFail() ? 1 : 0;
    }

    /**
     * 根据主播获取总收入
     */
    static function getTotalIncome(
        $userIds = [],
        $startTime = '',
        $endTime = '',
        $from = 0,
        $fromGroup = false
    ) {
        $where = [
            ['flag', 1],
            ['log_type', self::TYPE_INCOME]
        ];
        if ($startTime) $where[] = ['created_at', '>=', $startTime];
        if ($endTime) $where[] = ['created_at', '<', $endTime];
        if (is_array($from) && $from) {
            $query = self::where($where)->whereIn('from', $from);
        } elseif ($from) {
            $where[] = ['from', $from];
            $query = self::where($where);
        } else {
            $where[] = ['from', '<>', self::FROM_WITHDRAW_BACK];
            $query = self::where($where);
        }
        if (!empty($userIds)) $query = $query->whereIn('user_id', $userIds);

        //是否按照from分类
        if (!$fromGroup) {
            $data = $query->select(Db::raw('SUM(coin) as coin'))->first();
            return $data && $data->coin ? round($data->coin, 1) : 0;
        } else {
            $data = $query->select(Db::raw('SUM(coin) as coin, `from`'))->groupBy('from')->get()->toArray();
            $info = [];
            foreach ($data as $item) $info[$item['from']] = $item['coin'];
            return $info;
        }
    }

    /**
     * 根据主播获取总流水（不算非用户消费）
     */
    static function getTotalConsume($userIds = [], $startTime = '', $endTime = '', $from = 0)
    {
        $where = [
            ['log_type', self::TYPE_CONSUME],
            ['flag', 1],
        ];
        if ($startTime) $where[] = ['created_at', '>=', $startTime];
        if ($endTime) $where[] = ['created_at', '<', $endTime];
        if ($from == 0) {
            //有效计算来源
            $validFrom = [
                self::FROM_SEND_GIFT,
                self::FROM_SEND_PRIVATE_MSG_OUT,
                self::FROM_VOICECALL_OUT,
                self::FROM_VIDEOCALL_OUT,
                self::FROM_QUICK_VOICE_OUT,
                self::FROM_QUICK_VIDEO_OUT
            ];
            $query = self::where($where)->whereIn('from', $validFrom);
        } elseif (is_array($from) && $from) {
            $query = self::where($where)->whereIn('from', $from);
        } else {
            $where[] = ['from', $from];
            $query = self::where($where);
        }
        $data = $query->whereIn('op_user_id', $userIds)->select(Db::raw('SUM(coin) as coin'))->first();
        return $data && $data->coin ? $data->coin : 0;
    }

    /**
     * 获取有收益的主播数
     */
    static function checkHostCount($userIds = [], $startTime = '', $endTime = '', $dataType = 'count')
    {
        $where = [
            ['flag', 1],
            ['log_type', self::TYPE_INCOME]
        ];
        $where = [];
        if ($startTime) $where[] = ['created_at', '>=', $startTime];
        if ($endTime) $where[] = ['created_at', '<', $endTime];
        if ($dataType == 'uid') {
            return array_unique(self::where($where)->whereIn('user_id', $userIds)->pluck('user_id')->toArray());
        } else {
            $data = self::where($where)->whereIn('user_id', $userIds)->select(Db::raw('count(distinct user_id) as ctn'))->first();
            return $data && $data->ctn ? $data->ctn : 0;
        }
    }

    /**
     * 总消费人数
     */
    static function getConsumeCount(
        $startTime = '',
        $endTime = '',
        $type = 'count',
        $channel = '',
        $from = 0
    ) {
        $where = [
            ['flag', 1],
            ['log_type', self::TYPE_CONSUME]
        ];
        //兼容非数组
        if ($from && !is_array($from)) $from = [$from];
        if (!$from) {
            $where[] = ['from', '<>', self::FROM_WITHDRAW];
            $where[] = ['from', '<>', self::FROM_SYS_COST];
        }

        //时间范围
        if ($startTime) $where[] = ['coin_log.created_at', '>=', (string)$startTime];
        if ($endTime) $where[] = ['coin_log.created_at', '<', (string)$endTime];

        //指定渠道
        if ($channel) {
            $query = Db::table('coin_log')->join('user', function ($join) use ($where, $channel) {
                $where[] = ['channel', $channel];
                $join->on('user.id', '=', 'coin_log.user_id')->where($where);
            });
        } else {
            $query = self::where($where);
        }

        //指定来源
        if ($from) $query = $query->whereIn('from', $from);

        if ('count' == $type) {
            $data = $query->select(Db::raw('count(distinct user_id) as ctn'))->first();
        } elseif ('coin' == $type) {
            $data = $query->select(Db::raw('SUM(coin) as ctn'))->first();
        }
        return $data && $data->ctn ? $data->ctn : 0;
    }

    /**
     * 主播实际名义礼物收入
     */
    static function getSysGiftCoin($startTime = '', $endTime = '')
    {
        $where = [
            ['flag', 1],
            ['log_type', self::TYPE_INCOME],
            ['from', self::FROM_GET_SYSGIFT],
        ];
        if ($startTime) $where[] = ['created_at', '>=', (string)$startTime];
        if ($endTime) $where[] = ['created_at', '<', (string)$endTime];
        $data = self::where($where)->select(Db::raw('SUM(coin) as ctn'))->first();
        return $data && $data->ctn ? $data->ctn : 0;
    }

    /**
     * 获取流水类型
     */
    static function getCallFrom($callType = VideoCall::CALL_TYPE, $callFrom = CallBase::FROM_MAIN, $type = 'out')
    {
        $isVoice = $callType == VoiceCall::CALL_TYPE;
        log_info(__CLASS__ . "==CallType:{$callType}==CallFrom:{$callFrom}==Type:{$type}");
        if ($type == 'out') {
            switch ($callFrom) {
                case CallBase::FROM_DISCOUNT_CALL:
                    return self::FROM_DISCOUNT_VIDEO_CALL_OUT;
                case CallBase::FROM_QUICK_MESSAGE:
                    return $isVoice ? self::FROM_QUICK_VOICE_OUT : self::FROM_QUICK_VIDEO_OUT;
                default:
                    return $isVoice ? self::FROM_VOICECALL_OUT : self::FROM_VIDEOCALL_OUT;
            }
        } else {
            switch ($callFrom) {
                case CallBase::FROM_DISCOUNT_CALL:
                    return self::FROM_DISCOUNT_VIDEO_CALL_IN;
                case CallBase::FROM_QUICK_MESSAGE:
                    return $isVoice ? self::FROM_QUICK_VOICE_IN : self::FROM_QUICK_VIDEO_IN;
                default:
                    return $isVoice ? self::FROM_VOICECALL_IN : self::FROM_VIDEOCALL_IN;
            }
        }
    }

    /**
     * 用户是否有某类金币消耗
     */
    static function checkConsumeFrom($userId = 0, $opUserId = 0, $from = 0)
    {
        $where = [
            ['user_id', $userId],
            ['op_user_id', $opUserId],
            ['from', $from],
            ['flag', 1]
        ];
        return self::where($where)->orderBy('id', 'desc')->first();
    }

    static function getDataByOrderId($orderId,$userId)
    {
        $data = self::where('order_id',$orderId)->where('user_id',$userId)->get();

        if (empty($data))
        {
            return false;
        }

        return $data->toArray();
    }
}
